package com.xingzhi.shortvideosharingplatform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xingzhi.shortvideosharingplatform.dto.VideoFavoriteDTO;
import com.xingzhi.shortvideosharingplatform.mapper.VideoFavoriteMapper;
import com.xingzhi.shortvideosharingplatform.model.VideoFavorite;
import com.xingzhi.shortvideosharingplatform.service.SystemNotificationService;
import com.xingzhi.shortvideosharingplatform.service.UserBehaviorLogsService;
import com.xingzhi.shortvideosharingplatform.service.VideoFavoriteService;
import com.xingzhi.shortvideosharingplatform.service.VideoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class VideoFavoriteServiceImpl extends ServiceImpl<VideoFavoriteMapper, VideoFavorite> implements VideoFavoriteService {

    @Autowired
    private VideoService videoService;
    
    @Autowired
    private SystemNotificationService notificationService;
    
    @Autowired
    private UserBehaviorLogsService behaviorLogsService;

    @Override
    @Transactional
    public boolean addVideoToFolder(VideoFavoriteDTO favoriteDTO) {
        // 检查收藏夹ID列表是否为空
        if (CollectionUtils.isEmpty(favoriteDTO.getFolderIds())) {
            log.error("收藏视频失败: 收藏夹ID列表为空");
            return false;
        }

        try {
            log.info("开始收藏视频: userId={}, videoId={}, folderIds={}", 
                favoriteDTO.getUserId(), favoriteDTO.getVideoId(), favoriteDTO.getFolderIds());
            
            // 过滤掉已经收藏过的收藏夹
            List<Long> folderIdsToAdd = new ArrayList<>();
            for (Long folderId : favoriteDTO.getFolderIds()) {
                if (!isVideoInFolder(favoriteDTO.getUserId(), favoriteDTO.getVideoId(), folderId)) {
                    folderIdsToAdd.add(folderId);
                }
            }
            
            log.info("需要新增收藏的文件夹数: {}", folderIdsToAdd.size());
            
            // 如果没有需要新增的收藏夹，直接返回成功
            if (folderIdsToAdd.isEmpty()) {
                log.info("没有新增收藏夹，操作完成");
                return true;
            }
            
            // 批量添加收藏记录
            int insertRows = baseMapper.batchInsertVideoFavorites(
                favoriteDTO.getUserId(),
                favoriteDTO.getVideoId(),
                folderIdsToAdd
            );
            log.info("成功添加收藏记录: {} 条", insertRows);
            
            // 不管是否首次收藏，都记录用户行为和发送通知
            log.info("记录用户行为并发送通知: userId={}, videoId={}", 
                favoriteDTO.getUserId(), favoriteDTO.getVideoId());
            
            // 记录用户行为
            boolean logSuccess = behaviorLogsService.logFavoriteBehavior(favoriteDTO.getUserId(), favoriteDTO.getVideoId());
            log.info("记录用户收藏行为: {}", logSuccess ? "成功" : "失败");
            
            // 增加视频收藏数
            boolean incrementSuccess = videoService.incrementFavoriteCount(favoriteDTO.getVideoId());
            log.info("增加视频收藏数: {}", incrementSuccess ? "成功" : "失败");
            
            // 发送通知给视频作者
            Long authorId = videoService.getVideoAuthorId(favoriteDTO.getVideoId());
            log.info("获取视频作者ID: {}", authorId);
            
            if (authorId != null && !authorId.equals(favoriteDTO.getUserId())) {
                boolean notifySuccess = notificationService.sendFavoriteNotification(authorId, favoriteDTO.getUserId(), favoriteDTO.getVideoId());
                log.info("发送收藏通知: {}", notifySuccess ? "成功" : "失败");
            } else {
                log.info("不需要发送通知: 作者为空或与收藏者相同");
            }
            
            return insertRows > 0;
        } catch (Exception e) {
            log.error("收藏视频失败: userId={}, videoId={}, folderIds={}", 
                    favoriteDTO.getUserId(), favoriteDTO.getVideoId(), favoriteDTO.getFolderIds(), e);
            throw e;
        }
    }

    @Override
    @Transactional
    public boolean removeVideoFromFolder(Long userId, Long videoId, Long folderId) {
        // 检查是否已收藏
        if (!isVideoInFolder(userId, videoId, folderId)) {
            return false;
        }
        
        try {
            // 删除特定收藏夹中的收藏记录
            LambdaQueryWrapper<VideoFavorite> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(VideoFavorite::getUserId, userId)
                       .eq(VideoFavorite::getVideoId, videoId)
                       .eq(VideoFavorite::getFolderId, folderId);
            boolean success = remove(queryWrapper);
            
            log.info("从特定收藏夹移除收藏: userId={}, videoId={}, folderId={}, success={}", 
                    userId, videoId, folderId, success);
            
            // 判断该视频是否不再被该用户收藏
            if (!isVideoFavorited(userId, videoId)) {
                log.info("视频不再被用户收藏，更新计数和行为记录: userId={}, videoId={}", userId, videoId);
                
                // 减少视频收藏数
                videoService.decrementFavoriteCount(videoId);
                
                // 删除用户行为记录
                behaviorLogsService.removeUserFavoriteBehavior(userId, videoId);
            }
            
            return success;
        } catch (Exception e) {
            log.error("取消收藏视频失败: userId={}, videoId={}, folderId={}", userId, videoId, folderId, e);
            throw e;
        }
    }
    
    @Override
    @Transactional
    public boolean removeAllVideoFavorites(Long userId, Long videoId) {
        // 检查是否有收藏记录
        if (!isVideoFavorited(userId, videoId)) {
            log.info("没有找到收藏记录，无需取消: userId={}, videoId={}", userId, videoId);
            return false;
        }
        
        try {
            log.info("开始取消所有收藏: userId={}, videoId={}", userId, videoId);
            
            // 查询有多少收藏记录
            LambdaQueryWrapper<VideoFavorite> countQuery = new LambdaQueryWrapper<>();
            countQuery.eq(VideoFavorite::getUserId, userId)
                     .eq(VideoFavorite::getVideoId, videoId);
            long favoriteCount = count(countQuery);
            log.info("找到收藏记录数: {}", favoriteCount);
            
            // 删除所有收藏记录
            LambdaQueryWrapper<VideoFavorite> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(VideoFavorite::getUserId, userId)
                       .eq(VideoFavorite::getVideoId, videoId);
            boolean success = remove(queryWrapper);
            
            if (success) {
                log.info("已删除所有收藏记录，现在更新视频收藏计数和用户行为记录");
                
                // 减少视频收藏数（只减少一次）
                videoService.decrementFavoriteCount(videoId);
                
                // 删除用户行为记录
                behaviorLogsService.removeUserFavoriteBehavior(userId, videoId);
            }
            
            return success;
        } catch (Exception e) {
            log.error("取消所有收藏失败: userId={}, videoId={}", userId, videoId, e);
            throw e;
        }
    }

    @Override
    public List<Long> getVideoIdsByFolderId(Long folderId) {
        LambdaQueryWrapper<VideoFavorite> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VideoFavorite::getFolderId, folderId)
                   .orderByDesc(VideoFavorite::getCreatedTime);
                   
        List<VideoFavorite> list = list(queryWrapper);
        
        return list.stream()
                  .map(VideoFavorite::getVideoId)
                  .collect(Collectors.toList());
    }

    @Override
    public boolean isVideoInFolder(Long userId, Long videoId, Long folderId) {
        LambdaQueryWrapper<VideoFavorite> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VideoFavorite::getUserId, userId)
                   .eq(VideoFavorite::getVideoId, videoId)
                   .eq(VideoFavorite::getFolderId, folderId);
                   
        return count(queryWrapper) > 0;
    }
    
    @Override
    public boolean isVideoFavorited(Long userId, Long videoId) {
        LambdaQueryWrapper<VideoFavorite> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VideoFavorite::getUserId, userId)
                   .eq(VideoFavorite::getVideoId, videoId);
                   
        return count(queryWrapper) > 0;
    }
    
    @Override
    public List<Long> getFolderIdsByUserAndVideo(Long userId, Long videoId) {
        LambdaQueryWrapper<VideoFavorite> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(VideoFavorite::getFolderId)
                   .eq(VideoFavorite::getUserId, userId)
                   .eq(VideoFavorite::getVideoId, videoId);
                   
        List<VideoFavorite> list = list(queryWrapper);
        
        return list.stream()
                  .map(VideoFavorite::getFolderId)
                  .collect(Collectors.toList());
    }
} 